package com.example.common.grpc;

import com.example.common.constants.ServiceNames;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 服务器ID生成器
 * 为每个服务实例分配唯一的服务器ID
 * 
 * @author: Allen
 * @create: 2025/7/3 22:30
 * @description: 服务器ID生成和管理
 **/
@Slf4j
@Component
public class ServerIdGenerator {
    
    @Value("${spring.application.name}")
    private String applicationName;
    
    @Value("${server.id:0}")
    private int configuredServerId;

    /**
     * -- GETTER --
     *  获取当前服务器ID
     */
    @Getter
    private int serverId;
    /**
     * -- GETTER --
     *  获取服务类型
     */
    @Getter
    private ServiceNames serviceType;
    
    private static final AtomicInteger gateCounter = new AtomicInteger(1000);
    private static final AtomicInteger lobbyCounter = new AtomicInteger(2000);
    private static final AtomicInteger gameCounter = new AtomicInteger(3000);
    
    @PostConstruct
    public void init() {
        generateServerId();
        log.info("服务器ID初始化完成: applicationName={}, serverId={}, serviceType={}", 
                applicationName, serverId, serviceType);
    }
    
    /**
     * 生成服务器ID
     */
    private void generateServerId() {
        if (configuredServerId > 0) {
            // 使用配置的服务器ID
            serverId = configuredServerId;
            serviceType = ServiceNames.getServiceByServerId(serverId);
            if (serviceType == null) {
                throw new IllegalArgumentException("配置的服务器ID无效: " + serverId);
            }
        } else {
            // 自动生成服务器ID
            serviceType = getServiceTypeByName(applicationName);
            if (serviceType == null) {
                throw new IllegalArgumentException("无法识别的服务名称: " + applicationName);
            }
            
            serverId = generateNextServerId(serviceType);
        }
        
        log.info("服务器ID生成: {} -> {}", applicationName, serverId);
    }
    
    /**
     * 根据服务名称获取服务类型
     */
    private ServiceNames getServiceTypeByName(String serviceName) {
        for (ServiceNames service : ServiceNames.values()) {
            if (service.value().equals(serviceName)) {
                return service;
            }
        }
        return null;
    }
    
    /**
     * 生成下一个服务器ID
     */
    private int generateNextServerId(ServiceNames serviceType) {
        switch (serviceType) {
            case GATE:
                int gateId = gateCounter.getAndIncrement();
                if (gateId > ServiceNames.GATE.getEndId()) {
                    throw new RuntimeException("Gate服务ID超出范围: " + gateId);
                }
                return gateId;
            case LOBBY:
                int lobbyId = lobbyCounter.getAndIncrement();
                if (lobbyId > ServiceNames.LOBBY.getEndId()) {
                    throw new RuntimeException("Lobby服务ID超出范围: " + lobbyId);
                }
                return lobbyId;
            case GAME:
                int gameId = gameCounter.getAndIncrement();
                if (gameId > ServiceNames.GAME.getEndId()) {
                    throw new RuntimeException("Game服务ID超出范围: " + gameId);
                }
                return gameId;
            default:
                throw new IllegalArgumentException("不支持的服务类型: " + serviceType);
        }
    }

    /**
     * 获取服务名称
     */
    public String getServiceName() {
        return serviceType.value();
    }
    
    /**
     * 检查是否为指定服务类型
     */
    public boolean isServiceType(ServiceNames serviceType) {
        return this.serviceType == serviceType;
    }
    
    /**
     * 重置计数器（主要用于测试）
     */
    public static void resetCounters() {
        gateCounter.set(1000);
        lobbyCounter.set(2000);
        gameCounter.set(3000);
    }
} 